\section{std::result}
Result类型的错误处理，\rustinline{Result<T, E>}是一个用于返回和传播错误的类型。它是一个枚举变量：
\begin{itemize}
    \item Ok(T)：代表成功同时包含一个值。
    \item Err(E)：代表失败同时包含一个错误值。
\end{itemize}
\begin{rust}
enum Result<T, E> {
   Ok(T),
   Err(E),
}
\end{rust}
函数无论期望的值还是错误都返回Result。最常用的场景是I/O。简单的返回Result的函数如下：
\begin{rust}
#[derive(Debug)]
enum Version { Version1, Version2 }

fn parse_version(header: &[u8]) -> Result<Version, &'static str> {
    match header.get(0) {
        None => Err("invalid header length"),
        Some(&1) => Ok(Version::Version1),
        Some(&2) => Ok(Version::Version2),
        Some(_) => Err("invalid version"),
    }
}

let version = parse_version(&[1, 2, 3, 4]);
match version {
    Ok(v) => println!("working with version: {:?}", v),
    Err(e) => println!("error parsing header: {:?}", e),
}
\end{rust}
在Result上的模式匹配结果清晰而直接，Resutl有些方法：
\begin{rust}
let good_result: Result<i32, i32> = Ok(10);
let bad_result: Result<i32, i32> = Err(10);

// The `is_ok` and `is_err` methods do what they say.
assert!(good_result.is_ok() && !good_result.is_err());
assert!(bad_result.is_err() && !bad_result.is_ok());

// `map` consumes the `Result` and produces another.
let good_result: Result<i32, i32> = good_result.map(|i| i + 1);
let bad_result: Result<i32, i32> = bad_result.map(|i| i - 1);

// Use `and_then` to continue the computation.
let good_result: Result<bool, i32> = good_result.and_then(|i| Ok(i == 11));

// Use `or_else` to handle the error.
let bad_result: Result<i32, i32> = bad_result.or_else(|i| Ok(i + 20));

// Consume the result and return the contents with `unwrap`.
let final_awesome_result = good_result.unwrap();
\end{rust}
返回值一个常见的问题是不能处理失败。Result使用\rustinline{#[must_use]}属性注释，当Result结果被忽略的时候将引起编译器警告。为了在可能不报错的场景下返回有用的值对函数而言非常重要：
\begin{rust}
use std::io;

trait Write {
    fn write_all(&mut self, bytes: &[u8]) -> Result<(), io::Error>;
}
\end{rust}
\begin{note}
    write定义了io::Result,它是Result<T,io::error>类型。
\end{note}
当出现错误的时候不产生值，而是直接产生错误：
\begin{rust}
use std::fs::File;
use std::io::prelude::*;

let mut file = File::create("valuable_data.txt").unwrap();
// If `write_all` errors, then we'll never know, because the return
// value is ignored.
file.write_all(b"important message");
\end{rust}
如果你这样写编译器会给警告（通过unused\_must\_use避免）。如果你不想处理错误，结合expect函数断言即可。这将导致panic提供错误原因：
\begin{rust}
use std::fs::File;
use std::io::prelude::*;

let mut file = File::create("valuable_data.txt").unwrap();
file.write_all(b"important message").expect("failed to write message");
\end{rust}
你也可以简单的断言：
\begin{rust}
assert!(file.write_all(b"important message").is_ok());Run
\end{rust}
或者是使用\textbf{?}传播错误：
\begin{rust}
fn write_message() -> io::Result<()> {
    let mut file = File::create("valuable_data.txt")?;
    file.write_all(b"important message")?;
    Ok(())
}
\end{rust}
当写代码的时候调用一些函数返回Result类型的结果，错误处理可能很麻烦。\textbf{?}隐藏了错误在调用栈的传播：
\begin{rust}
use std::fs::File;
use std::io::prelude::*;
use std::io;

struct Info {
    name: String,
    age: i32,
    rating: i32,
}

fn write_info(info: &Info) -> io::Result<()> {
    // Early return on error
    let mut file = match File::create("my_best_friends.txt") {
           Err(e) => return Err(e),
           Ok(f) => f,
    };
    if let Err(e) = file.write_all(format!("name: {}\n", info.name).as_bytes()) {
        return Err(e)
    }
    if let Err(e) = file.write_all(format!("age: {}\n", info.age).as_bytes()) {
        return Err(e)
    }
    if let Err(e) = file.write_all(format!("rating: {}\n", info.rating).as_bytes()) {
        return Err(e)
    }
    Ok(())
}
\end{rust}
或者:
\begin{rust}
use std::fs::File;
use std::io::prelude::*;
use std::io;

struct Info {
    name: String,
    age: i32,
    rating: i32,
}

fn write_info(info: &Info) -> io::Result<()> {
    let mut file = File::create("my_best_friends.txt")?;
    // Early return on error
    file.write_all(format!("name: {}\n", info.name).as_bytes())?;
    file.write_all(format!("age: {}\n", info.age).as_bytes())?;
    file.write_all(format!("rating: {}\n", info.rating).as_bytes())?;
    Ok(())
}
\end{rust}
?结尾的表达式将结果打包到Ok中，如果结果是Err，则返回Err。


